import os
import shutil
import xlwings as xw
import openpyxl as px
from pathlib import Path

app = xw.App(visible=False, add_book=False)
source_path = os.path.join(os.getcwd(), '暂存文件')
dest_path = os.path.join(os.getcwd(), '现货数据日报表')

def bl(x):  ##文件名中月份如不如两位，补零

    if len(x) == 1:
        x = "0" + x
        return x
    else:
        return x


## 判断序列中所有的元素均为空值
def is_empty(value):  ##判断是否为空值
    if value is None:
        return True
    # elif isinstance(value, str) and value.strip() == '':
    # return True
    elif isinstance(value, (list, tuple, dict)) and len(value) == 0:
        return True
    else:
        return False


## 规范xlsx文件名
def gf_name(xls_name):
    import re
    str = re.findall(r"\d*\d+\d*", xls_name)
    ##使用bl(x)自定义函数
    new_file = str[0][0:4] + '-' + bl(str[1][0:2]) + \
               '-' + bl(str[2][0:2]) + '现货数据日报表.xlsx'
    return new_file  ##返回规范文件名


## 判断是否为空的序列
def is_empty_seq(seq):
    tar_seq = [[None, None, None] for x in range(10)]
    return seq == tar_seq


## 填充序列
def fill_sep(sep):
    fillsep = [[150, 298, 1499.98], [298, 299, 1499.99], [299, 300, 1500]]
    return fillsep


## 读取调频中标情况
def tiaopin(xls_name):
    tp_xls = os.path.join(os.getcwd(), '机组调频中标情况.xlsx')
    ws_workbook = app.books.open(tp_xls)  ##打开机组调频中标情况
    ws_worksheet = ws_workbook.sheets[0]
    workbook = app.books.open(xls_name)  # 打开当前需要统计的文件
    worksheet = workbook.sheets['1.公司现货综合信息']
    date_tp = worksheet.range('G3').value  ## 提取日期
    jz_1 = worksheet.range('F19').value  ## 机组编号1
    jz_2 = worksheet.range('F20').value  ## 机组编号2
    zb1_1 = worksheet.range('H19').value  ##1号机组段1调频中标情况
    zb1_2 = worksheet.range('I19').value  ##1号机组段2调频中标情况
    zb1_3 = worksheet.range('J19').value  ##1号机组段3调频中标情况
    zb1_4 = worksheet.range('K19').value  ##1号机组段4调频中标情况
    zb1_5 = worksheet.range('L19').value  ##1号机组段5调频中标情况
    zb2_1 = worksheet.range('H20').value  ##2号机组段1调频中标情况
    zb2_2 = worksheet.range('I20').value  ##2号机组段2调频中标情况
    zb2_3 = worksheet.range('J20').value  ##2号机组段3调频中标情况
    zb2_4 = worksheet.range('K20').value  ##2号机组段4调频中标情况
    zb2_5 = worksheet.range('L20').value  ##2号机组段5调频中标情况
    last_cell = ws_worksheet.range('A1').expand('table').last_cell  ##获取机组调频中标情况表中右下角单元格
    ws_worksheet.cells(last_cell.row + 1, 1).value = date_tp  # 写入日期
    ws_worksheet.cells(last_cell.row + 1, 2).value = jz_1  # 写入机组编号1
    ws_worksheet.cells(last_cell.row + 1, 3).value = zb1_1  # 1号机组段1调频中标情况
    ws_worksheet.cells(last_cell.row + 1, 4).value = zb1_2  # 1号机组段2调频中标情况
    ws_worksheet.cells(last_cell.row + 1, 5).value = zb1_3  # 1号机组段3调频中标情况
    ws_worksheet.cells(last_cell.row + 1, 6).value = zb1_4  # 1号机组段4调频中标情况
    ws_worksheet.cells(last_cell.row + 1, 7).value = zb1_5  # 1号机组段5调频中标情况

    ws_worksheet.cells(last_cell.row + 2, 1).value = date_tp  # 写入日期
    ws_worksheet.cells(last_cell.row + 2, 2).value = jz_2  # 写入机组编号2
    ws_worksheet.cells(last_cell.row + 2, 3).value = zb2_1  # 2号机组段1调频中标情况
    ws_worksheet.cells(last_cell.row + 2, 4).value = zb2_2  # 2号机组段2调频中标情况
    ws_worksheet.cells(last_cell.row + 2, 5).value = zb2_3  # 2号机组段3调频中标情况
    ws_worksheet.cells(last_cell.row + 2, 6).value = zb2_4  # 2号机组段4调频中标情况
    ws_worksheet.cells(last_cell.row + 2, 7).value = zb2_5  # 2号机组段5调频中标情况
    #print('{}调频情况统计完成'.format(xls_name))
    workbook.close()
    ws_workbook.save()
    ws_workbook.close()
    return


## 交易申报方案（虚拟单机时价格）
def jysbfa(new_file):
    sc_path1 = '批量上传'
    sc_path2 = '现货日报'
    sc_path3 = '交易方案申报'
    sc_path = os.path.join(sc_path1, sc_path2)
    shutil.copy(new_file, sc_path)
    # os.remove(new_file)
    file_mb1 = '交易申报方案.xlsx'

    workbook1 = app.books.open(new_file)
    worksheet1 = workbook1.sheets['1.公司现货综合信息']
    date_xh = worksheet1['G3'].value  # 提取日期
    name_xh = worksheet1['B5'].value  # 提取机组名称
    content_xh1 = worksheet1['F6:H15'].options(
        ndim=2).value  # 提取1#机组报价
    content_xh2 = worksheet1['I6:K15'].options(
        ndim=2).value  # 提取2#机组报价
    content_fhsx1 = worksheet1.range('G6').expand('down').value if not is_empty(
        worksheet1.range('G6').expand('down').value) else []  # 提取1#机组负荷上限
    content_fhsx2 = worksheet1.range('J6').expand('down').value if not is_empty(
        worksheet1.range('J6').expand('down').value) else []  # 提取2#机组负荷上限
    fhxx1 = content_xh1[0][0]  # 1机组负荷下限
    fhsx1 = content_fhsx1[-1] if not is_empty(content_fhsx1) else None  # 1机组负荷上限
    fhxx2 = content_xh2[0][0]  # 2机组负荷下限
    fhsx2 = content_fhsx2[-1] if not is_empty(content_fhsx2) else None  # 2机组负荷上限

    workbook_mb = app.books.open(
        os.path.join(sc_path1, file_mb1))  # 打开模板表
    worksheet_mb = workbook_mb.sheets[0]
    worksheet_mb.range('C15').options(
        ndim=2).value = content_xh1 if not is_empty_seq(content_xh1) else fill_sep(content_xh1)  # 放入1#机组报价
    worksheet_mb.range('G15').options(
        ndim=2).value = content_xh2 if not is_empty_seq(content_xh2) else fill_sep(content_xh2)  # 放入2#机组报价
    worksheet_mb.range('C9:C13').value = fhxx1 if not is_empty(fhxx1) else 150  # 放入1#机组申报下限
    worksheet_mb.range('D9:D13').value = fhsx1 if not is_empty(fhsx1) else 300  # 放入1#机组申报上限
    worksheet_mb.range('G9:G13').value = fhxx2 if not is_empty(fhxx2) else 150  # 放入2#机组申报下限
    worksheet_mb.range('H9:H13').value = fhsx2 if not is_empty(fhsx2) else 300  # 放入2#机组申报上限
    worksheet_mb.range('B3').value = date_xh.strftime(
        '%Y-%m-%d')  # 放入日期
    # worksheet_mb.range('A12').value = date_xh.strftime(
    #   '%Y-%m-%d')  # 放入日期
    worksheet_mb.range('C2').value = name_xh + '1#'  # 放入1#机组名称
    worksheet_mb.range('G2').value = name_xh + '2#'  # 放入2#机组名称~
    file_1 = date_xh.strftime('%Y-%m-%d') + file_mb1  # 按日期取一个新文件名
    # workbook1.close() #完成上传日前中标出力后再关闭
    workbook_mb.save()
    workbook_mb.close()
    shutil.copy(os.path.join(sc_path1, file_mb1), file_1)
    shutil.move(file_1, os.path.join(sc_path1, sc_path3))
    print('%s已导入' % file_1)
    return


def xhbjfa(new_file):  ## 现货报价方案
    from datetime import datetime
    import pandas as pd
    sc_path1 = '批量上传'
    sc_path4 = '现货中标及价格'
    file_mb2 = '现货中标出力及价格.xlsx'
    workbook1 = app.books.open(new_file)
    worksheet2 = workbook1.sheets['3.日前出清发电量数据']
    date_xh = worksheet2.range('B2').value
    name = '浍滨'
    if isinstance(date_xh, datetime):
        date_xh = worksheet2.range('B2').value  # 提取日期
        date_xh = date_xh.strftime('%Y-%m-%d')
    content_xh1 = worksheet2.range('D1:H193').options(
        pd.DataFrame, index=False).value  # 提取机组出清报价
    content_xh1 = content_xh1[['中标出力', '实际出力', '出清价格', '日内节点电价']]
    workbook_mb = app.books.open(
        os.path.join(sc_path1, file_mb2))  # 打开模板表
    worksheet_mb = workbook_mb.sheets[0]
    worksheet_mb.range('B2:B97').value = name + '1#'
    worksheet_mb.range('B98:B193').value = name + '2#'
    worksheet_mb.range('D2').options(
        index=False, header=False).value = content_xh1  # 放入机组出清报价
    file_1 = '现货中标出力及价格-' + date_xh + '.xlsx'  # 按日期取一个新文件名
    workbook1.close()
    workbook_mb.save()
    workbook_mb.close()
    shutil.copy(os.path.join(sc_path1, file_mb2), file_1)
    shutil.move(file_1, os.path.join(sc_path1, sc_path4))
    print('%s已导入' % file_1)
    return


# 日报汇总
def rbhz(dir_path):
    import pandas as pd
    # 设置综合厂用电率 2025年厂用电率0.095,网损率3.52%
    zhcyd = (1-0.095)*(1-0.0352)
    # 汇总现货日报表数据

    file_list = os.listdir(dir_path)
    dfs = []
    if len(file_list) != 0:
        for i in file_list:
            file = os.path.join(dir_path, i)
            #如何文件名后缀为.xlsx且前缀不包含_~$，则执行以下操作:
            if file.endswith('.xlsx') and not file.startswith('._'):
            
                #读取"3.日前出清发电量数据"工作表，提取前192行数据，提取A:K列数据
                wb=app.books.open(file)
                ws=wb.sheets['3.日前出清发电量数据']
                df1=ws.range('A1:K193').options(pd.DataFrame).value
                df1=df1.reset_index()
                df1['综合厂用电'] = zhcyd  #新增一列，综合厂用电率
                #读取"日前现货数据统计"工作表，提取前192行数据，提取P:Q列数据
                ws2=wb.sheets['日前现货数据统计']
                df2=ws2.range('P2:Q194').options(pd.DataFrame).value
                df2=df2.reset_index ()
                #新增一列调频补偿合计，合并P:Q列数据
                df2['调频补偿合计']=df2.iloc[:,0]+df2.iloc[:,1]
                df2=df2['调频补偿合计']             
                df1['调频补偿合计']=df2.values #将df2合并到df1
                dfs.append(df1)
                df = pd.concat(dfs)
                wb.close()
    df.dropna(subset=['时间'], inplace=True)  # 对无效数据进行清洗
    
    # 将df转换为csv文件

    df.to_csv('现货数据分析.csv', encoding='utf-8')
    # 读取现货数据分析.csv
    df = pd.read_csv('现货数据分析.csv', parse_dates=['日期'])

     #将日期转为字符型
    df['日期'] = df['日期'].astype('string')
    df['日期'] = df['日期'].apply(lambda x: x[:10])
    df['时间']=df['时间'].astype('string')
    #将日期转为字符型
    df['时间'].replace('1900-01-01 00:00:00', '23:59', inplace=True)
    df['时间'].replace('24:00', '23:59', inplace=True)
    
    df['时间'] = df['时间'].apply(lambda x: x[:5])
    # 调整时间字段
    df['时间'] = df['时间'].apply(lambda x: ' ' + x)
    df['datetime'] = df['日期'] + df['时间']
    df['datetime'] = df['datetime'].astype('datetime64[ns]') #将字符串转换为日期格式
        #将23:59替换为24:00 
    df['时间'] = df['时间'].astype('string')
    df['时间']=df['时间'].apply(lambda x: x.replace('23:59','24:00'))

    # 将中长期均价为空的数据进行填充
    df['中长期均价'].fillna(method='ffill', inplace=True) # type: ignore
    # 增加Cost字段（中长期均价与出清价差）
    df['cost'] = df['中长期均价'] - df['出清价格']
    # 如果中长期价格为空时，用中长期均价替换中长期价格
    m = df['中长期价格'].notna()
    df.loc[:, '中长期价格'] = df.loc[:, '中长期价格'].where(m, df.loc[:, '中长期均价'])
    # 增加日前与中长期电量差（发电量口径）
    df['日前与中长期电量差'] = df['中标出力'] - df['中长期电量']
    # 增加中长期电费
    df['中长期电费'] = df['中长期电量'] * df['中长期价格'] * df['综合厂用电'] / 4
    # 增加日前电费收入
    df['日前电费收入'] = df['日前与中长期电量差'] * df['出清价格'] * df['综合厂用电'] / 4
    # 增加实时电量与日前电量差
    df['实时电量与日前电量差'] = df['实际出力'] - df['中标出力']
    # 增加实时电费收入
    df['实时电费收入'] = df['实时电量与日前电量差'] * df['日内节点电价'] * df['综合厂用电'] / 4
    # 增加电能量收入
    df['电能量收入'] = df['中长期电费'] + df['日前电费收入'] + df['实时电费收入']
    # 增加电费变动成本
    df['电费变动成本'] = df['变动成本'] * df['实际出力'] * df['综合厂用电'] / 4
    # 增加电能量盈亏
    df['电能量盈亏'] = df['电能量收入'] - df['电费变动成本']


    # df.drop(df.iloc[:, 12:16], axis=1, inplace=True)
    # df.drop(df.iloc[:, 13:14], axis=1, inplace=True)
    df=df.iloc[:,1:] #删除第一列
    df.to_excel('现货日前数据.xlsx', index=False)
    print('已完成导入数据')
    return
def rep_2023(source_path):
    from datetime import datetime
    # 遍历暂存文件夹中的所有文件和子文件夹
    for filename in os.listdir(source_path):
        # 检查文件名中是否有"2023"
        if "2023" in filename:
            # 构造新文件名，将"2023"替换为"2024"
            new_filename = filename.replace("2023", "2024")
            # 构造原文件和新文件的完整路径
            original_file = os.path.join(source_path, filename)
            new_file = os.path.join(source_path, new_filename)
            # 重命名文件
            os.rename(original_file, new_file)
            print(f'Renamed "{filename}" to "{new_filename}"')
    # 打开暂存文件夹中的所有xlsx文件“1.公司现货综合信息”工作表，将G3单元格中的2023替换为2024,xlsx文件不应是前缀有～$的文件
    for filename in os.listdir(source_path):
        if filename.endswith(".xlsx") and not filename.startswith("~$"):
            file_path = os.path.join(source_path, filename)
            wb = px.load_workbook(file_path)
            ws = wb['1.公司现货综合信息']
            cell=ws['G3']
            #将G3单元格中的2023替换为2024，并将字符串格式转换为日期格式
            #如果cell.value是字符串格式:
            if isinstance(cell.value,str):
                cell.value=cell.value.replace("2023", "2024")
            #否则将cell.value转换为字符串格式
            else:
                
                cell.value="{:%Y-%m-%d}".format(cell.value) #将日期格式转换为字符串格式
                cell.value = cell.value.replace("2023", "2024")
            #cell.value = datetime.strptime(cell.value,'%Y-%m-%d') #将字符串格式转换为日期格式
            print(cell.value)
            wb.save(file_path)
            wb.close()


#暂存文件下所有xlsx文件：
for file in os.listdir(source_path):
    if file.endswith('.xlsx'):
        new_filename = gf_name(file)  ## 规范xlsx文件名
        new_filename = file.replace(file, new_filename) #替换文件名
        source_file = os.path.join(source_path, file)  #源文件路径
        dest_file = os.path.join(dest_path, new_filename) # 目标文件路径
        #目标文件路径不存在时，复制文件：
        if not os.path.exists(dest_file):
            shutil.copy(source_file, dest_file)
        #os.rename(source_file, dest_file) #
        tiaopin(dest_file)  # 统计调频情况
        issc = 'N'
        # issc = input('{}是否直接上传至信息平台（Y/N)'.format(file))
        # 导入到平台功能
        if issc.upper() == 'Y':
            jysbfa(dest_file)  ## 交易申报方案（单机虚拟报价）
            xhbjfa(dest_file)  ## 现货报价方案
rep_2023(source_path)  ##将暂存文件夹中的文件名中的2023替换为2024
rbhz(dest_path)  ##将现货数据日报表中的数据汇总

app.quit()